package re;

import fa.FARule;
import nfa.NFADesign;
import nfa.NFARulebook;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @author haoly
 * @title Repeat
 * @date 2025/4/17 08:51
 * @description 重复正则表达式
 */
public class Repeat<T extends Pattern> extends Pattern{
    private final T pattern;

    public Repeat(T pattern) {
        this.pattern = pattern;
    }

    @Override
    public int precedence() {
        return 2;
    }

    @Override
    public NFADesign toNFADesign() {
        NFADesign firstNFADesign = pattern.toNFADesign();

        Object startState = new Object();
        Set acceptStates = new HashSet(firstNFADesign.getAcceptStates());
        acceptStates.add(startState);

        List<FARule> rules = new ArrayList<>();
        rules.addAll(firstNFADesign.getRulebook().getRules());
        List<FARule> freeMoves = new ArrayList<>();
        for (Object state : firstNFADesign.getAcceptStates()) {
            freeMoves.add(new FARule(state, null, firstNFADesign.getStartState()));
        }
        freeMoves.add(new FARule(startState, null, firstNFADesign.getStartState()));
        rules.addAll(freeMoves);

        NFARulebook rulebook = new NFARulebook(rules);
        return new NFADesign(startState, acceptStates, rulebook);
    }

    @Override
    public String toString() {
        return pattern.bracket(this.precedence()) + "*";
    }
}
